import { Component } from 'react';
import type { ConnectProps } from 'umi';
import { history } from 'umi';
import { connect } from 'umi';
import { Tag, message } from 'antd';
import groupBy from 'lodash/groupBy';
import moment from 'moment';
import type { NoticeItem } from '@/models/global'; // 导入 NoticeItem 类型，来自项目中的 global 模型
import type { CurrentUser } from '@/models/user';
import type { ConnectState } from '@/models/connect';
import NoticeIcon from '../NoticeIcon';
import styles from './index.less';

export type GlobalHeaderRightProps = {
  // 定义 GlobalHeaderRight 组件的 props 类型
  notices?: NoticeItem[]; // 定义 notices 属性，是一个 NoticeItem 类型的数组
  currentUser?: CurrentUser; // 定义 currentUser 属性，是一个 CurrentUser 类型
  fetchingNotices?: boolean; // 定义 fetchingNotices 属性，表示是否正在获取通知数据
  onNoticeVisibleChange?: (visible: boolean) => void; // 定义 onNoticeVisibleChange 属性，是一个回调函数，用于通知图标弹出层显示状态变化时的处理
  onNoticeClear?: (tabName?: string) => void; // 定义 onNoticeClear 属性，是一个回调函数，用于清空某个分类下的通知数据
} & Partial<ConnectProps>; // GlobalHeaderRightProps 类型是 ConnectProps 类型的子集

class GlobalHeaderRight extends Component<GlobalHeaderRightProps> {
  // 定义 GlobalHeaderRight 组件类，继承自 React 的 Component 类

  componentDidMount() {
    // 组件挂载完成后触发的生命周期函数
    const { dispatch } = this.props; // 从 props 中获取 dispatch 方法

    if (dispatch) {
      // 如果 dispatch 存在
      dispatch({
        // 分发一个 action
        type: 'global/fetchNotices', // action 类型为 'global/fetchNotices'
      });
    }
  }
// 定义一个方法，用于更新通知项的已读状态
  changeReadState = (clickedItem: NoticeItem): void => {
    const { id } = clickedItem; // 从 clickedItem 中获取 id 属性
    const { dispatch } = this.props; // 从 props 中获取 dispatch 方法

    if (dispatch) {
      // 如果 dispatch 存在
      dispatch({
        // 分发一个 action
        type: 'global/changeNoticeReadState', // action 类型为 'global/changeNoticeReadState'
        payload: id, // action 的 payload 是 clickedItem 的 id
      });
    }
  };
// 定义一个方法，用于处理清空通知分类的操作
  handleNoticeClear = (title: string, key: string) => {

    const { dispatch } = this.props; // 从 props 中获取 dispatch 方法
    message.success(`${'Emptied'} ${title}`); // 显示一个提示消息，表示成功清空通知

    if (dispatch) {
      // 如果 dispatch 存在
      dispatch({
        // 分发一个 action
        type: 'global/clearNotices', // action 类型为 'global/clearNotices'
        payload: key, // action 的 payload 是通知分类的 key
      });
    }
  };
// 定义一个方法，用于处理通知数据
  getNoticeData = (): Record<string, NoticeItem[]> => {
    const { notices = [] } = this.props; // 从 props 中获取 notices 属性，如果不存在则默认为空数组
    if (!notices || notices.length === 0 || !Array.isArray(notices)) {
      // 如果 notices 为空或不是数组
      return {}; // 返回一个空对象
    }
    const newNotices = notices.map((notice) => {
      // 遍历通知数据列表，对每个通知项进行处理
      const newNotice = { ...notice }; // 复制当前通知项对象，避免直接修改原对象
      if (newNotice.datetime) {
        // 如果通知项有 datetime 属性
        newNotice.datetime = moment(notice.datetime as string).fromNow(); // 使用 moment 库格式化 datetime 属性为相对时间
      }
      if (newNotice.id) {
        // 如果通知项有 id 属性
        newNotice.key = newNotice.id; // 将 id 属性值赋给 key 属性
      }
      if (newNotice.extra && newNotice.status) {
        // 如果通知项有 extra 和 status 属性
        const color = {
          todo: '',
          processing: 'blue',
          urgent: 'red',
          doing: 'gold',
        }[newNotice.status]; // 根据 status 属性的值获取对应的标签颜色
        newNotice.extra = (
          <Tag
            color={color}
            style={{
              marginRight: 0,
            }}
          >
            {newNotice.extra}
          </Tag>
        ); // 将 extra 属性值转换为一个带有颜色的标签组件
      }

      return newNotice; // 返回处理后的通知项对象
    });
    return groupBy(newNotices, 'type'); // 将处理后的通知项列表按照 type 属性进行分组，返回一个分组后的对象
  };
// 定义一个方法，用于获取未读通知数据
  getUnreadData = (noticeData: Record<string, NoticeItem[]>) => {

    const unreadMsg: Record<string, number> = {}; // 定义一个对象，用于存储每个分类的未读通知数
    Object.keys(noticeData).forEach((key) => {
      // 遍历通知数据分组的对象
      const value = noticeData[key]; // 获取当前分类的通知列表

      if (!unreadMsg[key]) {
        // 如果 unreadMsg 对象中没有当前分类的属性
        unreadMsg[key] = 0; // 初始化当前分类的未读通知数为 0
      }

      if (Array.isArray(value)) {
        // 如果当前分类的通知列表是一个数组
        unreadMsg[key] = value.filter((item) => !item.read).length; // 获取未读通知数，即未读通知项的数量
      }
    });
    return unreadMsg; // 返回未读通知数据对象
  };

  render() {
    // 渲染组件
    const { currentUser, fetchingNotices, onNoticeVisibleChange } = this.props;
    const noticeData = this.getNoticeData(); // 调用 getNoticeData 方法，获取处理后的通知数据
    const unreadMsg = this.getUnreadData(noticeData); // 调用 getUnreadData 方法，获取未读通知数据
    return (
      // 返回渲染结果
      <NoticeIcon
        className={styles.action}
        count={currentUser && currentUser.unreadCount} // 通知图标上显示未读通知数
        onItemClick={(item) => {
          this.changeReadState(item as NoticeItem); // 点击通知项时，更新通知项的已读状态
        }}
        loading={fetchingNotices} // 是否正在加载通知数据
        clearText="清空" // 清空按钮的文本
        viewMoreText={<a onClick={() => history.push(`/notification/list`)}>查看更多</a>} // 查看更多按钮的文本
        onClear={this.handleNoticeClear} // 点击清空按钮时的回调函数
        onPopupVisibleChange={onNoticeVisibleChange} // 通知图标弹出层显示状态变化时的回调函数
        clearClose // 点击清空按钮后，自动关闭通知弹出层
      >
        <NoticeIcon.Tab
          tabKey="notification"
          count={unreadMsg.notification}
          list={noticeData.notification}
          title="通知"
          emptyText="You have viewed all notifications" // 通知分类为空时的提示文本
          showViewMore // 显示查看更多按钮
        />
        <NoticeIcon.Tab
          tabKey="message"
          count={unreadMsg.message}
          list={noticeData.message}
          title="活动"
          emptyText="You have read all messages" // 活动分类为空时的提示文本
          showViewMore // 显示查看更多按钮
        />
      </NoticeIcon> // 返回 NoticeIcon 组件，并传递所需的 props
    );
  }
}

export default connect(({ user, global, loading }: ConnectState) => ({
  currentUser: user.currentUser, // 将 user 模型中的 currentUser 状态映射到 currentUser 属性
  collapsed: global.collapsed, // 将 global 模型中的 collapsed 状态映射到 collapsed 属性
  fetchingMoreNotices: loading.effects['global/fetchMoreNotices'], // 将 loading 中的 fetchMoreNotices 属性映射到 fetchingMoreNotices 属性
  fetchingNotices: loading.effects['global/fetchNotices'], // 将 loading 中的 fetchNotices 属性映射到 fetchingNotices 属性
  notices: global.notices, // 将 global 模型中的 notices 状态映射到 notices 属性
}))(GlobalHeaderRight);
